ident = '$Id: binders.py 127 2006-06-23 23:40:43Z trevor $'
'''The Binder and Instance UI components'''
import sys, wx, rex, common, base, icon_manager, images, re
from xml.dom		import minidom

ID_INS_CREATE		= 120
ID_INS_EDIT			= 121
ID_INS_DELETE		= 122
ID_INS_PREVIEW		= 123
ID_INS_CLONE		= 124
ID_INS_COPY			= 125
ID_INS_PASTE		= 126

class instances_control( wx.Panel ):
	def __init__( self, bin ):
		wx.Panel.__init__( self, bin.account.window.bbook, -1 )
		self.bin		= bin
		self.account 	= bin.account
		self.create_menu_items()
		# Connect a timer to this frame
		self.timer = wx.Timer( self )
		self.Bind( wx.EVT_TIMER, self.OnTimer )
		# Create the top bar
		self.topbar = wx.BoxSizer( wx.HORIZONTAL )
		# The new button
		self.new_button = wx.BitmapButton( self, -1, images.getNewInstanceBitmap(), size=common.button_size, style=wx.NO_BORDER )
		self.new_button.Bind( wx.EVT_BUTTON, self.OnInstanceCreate )
		self.topbar.Add( self.new_button, 0 )
		# create the filder dropdown
		variables = [""]
		for var in bin.variables:
			variables.append( var['name'] )
		self.variable_choice = wx.Choice( self, -1, choices=variables )
		self.variable_choice.SetSelection( 0 )
		self.variable_choice.Bind( wx.EVT_CHOICE, self.OnShowByChange )
		self.topbar.Add( self.variable_choice, 1, wx.EXPAND )
		# the relation button
		self.find_rel_button = wx.BitmapButton( self, -1, images.getEqualsBitmap(), size=common.button_size, style=wx.NO_BORDER )
		self.find_rel_button.Bind( wx.EVT_BUTTON, self.OnRelChange )
		self.find_rel_button.Enable( False )
		self.topbar.Add( self.find_rel_button, 0 )
		# The find text box
		self.find_text = wx.TextCtrl( self, -1, '', style=wx.TE_PROCESS_ENTER )
		self.find_text.Enable( False )
		self.find_text.Bind( wx.EVT_TEXT, self.OnFindTextKeyPress )
		self.find_text.Bind( wx.EVT_TEXT_ENTER, self.GetNext )
		self.topbar.Add( self.find_text, 2, wx.EXPAND )

		#~ # Label
		#~ self.topbar.Add( wx.StaticText( self, -1, "   Show " ), 0, wx.GROW | wx.NORTH, 3 )

		#~ # The finding selector
		#~ self.rpp_choice = wx.Choice( self, ID_RPP, choices=["10 per page", "30 per page","50 per page", "100 per page"] )
		#~ self.rpp_choice.SetSelection( 1 )
		#~ self.Bind( wx.EVT_CHOICE, self.OnRPPChange, id=ID_RPP )
		#~ self.topbar.Add( self.rpp_choice, 1, wx.EXPAND )
		#self.find_by = 1	# Find by ID by default

		# Create the get button
		#~ self.get_button = wx.Button( self, ID_GET_BUTTON, "Get" )
		#~ self.Bind( wx.EVT_BUTTON, self.OnGet, id=ID_GET_BUTTON )
		#~ self.topbar.Add( self.get_button, 1, wx.EXPAND )
		# zoom
		self.zoom_button = wx.BitmapButton( self, -1, images.getZoomBitmap(), size=common.button_size, style=wx.NO_BORDER )
		self.zoom_button.Bind( wx.EVT_BUTTON, self.OnZoom )
		self.topbar.Add( self.zoom_button, 0 )
		self.close_button = wx.BitmapButton( self, -1, images.getCloseBitmap(), size=common.button_size, style=wx.NO_BORDER )
		self.close_button.Bind( wx.EVT_BUTTON, self.OnClose )
		self.topbar.Add( self.close_button, 0 )
		# Enable the top bar controls
		#self.reset_values()
		#self.filter_dirty = False
		# Create the list
		self.list = wx.ListCtrl( self, -1, style=wx.LC_REPORT )
		self.il = wx.ImageList(16, 16)
		# Load our images
		self.instance_icon 	= self.il.Add( images.getInstanceBitmap() )
		self.list.SetImageList( self.il, wx.IMAGE_LIST_SMALL )
		self.list.Bind( wx.EVT_LEFT_DCLICK, self.OnItemDoubleClick )
		# default?
		#self.list.Bind( wx.EVT_RIGHT_DOWN, self.OnListRightClick )
		# for wxGTK
		self.list.Bind( wx.EVT_RIGHT_UP, self.OnListRightClick )
		# for wxMSW
		self.list.Bind( wx.EVT_COMMAND_RIGHT_CLICK, self.OnListRightClick )
		self.list.Bind( wx.EVT_LIST_ITEM_SELECTED, self.OnItemActivated )
		self.list.Bind( wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated )
		# Add it's columns
		info = wx.ListItem()
		info.m_mask = wx.LIST_MASK_TEXT # | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT
		info.m_format = 0
		info.m_text = "ID"
		self.list.InsertColumnInfo(0, info)
		info.m_text = "Name"
		self.list.InsertColumnInfo(1, info)
		# Create the bottom bar
		self.botbar = wx.BoxSizer( wx.HORIZONTAL )
		# Create prev and next buttons
		self.prev_button = wx.BitmapButton( self, -1, images.getLeftArrowBitmap(), style=wx.NO_BORDER )
		self.prev_button.Bind( wx.EVT_BUTTON, self.GetPrev )
		self.prev_button.Enable( False )
		self.botbar.Add( self.prev_button, 0, wx.EXPAND )
		self.pager = wx.StaticText( self, -1, " " )
		self.botbar.Add( self.pager, 1, wx.EXPAND | wx.ALIGN_CENTER )
		self.next_button = wx.BitmapButton( self, -1, images.getRightArrowBitmap(), style=wx.NO_BORDER )
		self.next_button.Bind( wx.EVT_BUTTON, self.GetNext )
		self.botbar.Add( self.next_button, 0, wx.EXPAND )
		self.reset_values()
		# The whole mess
		self.sizer = wx.BoxSizer( wx.VERTICAL )
		self.sizer.Add( self.topbar, 0, wx.EXPAND )
		self.sizer.Add( self.list, 1, wx.EXPAND )
		self.sizer.Add( self.botbar, 0, wx.EXPAND )
		# Set the drag and drop events
		self.list.Bind( wx.EVT_LIST_BEGIN_DRAG, self.OnBeginDrag )
		self.SetSizer( self.sizer )
		self.SetAutoLayout( 1 )
		if self.account.window: self.account.window.SetStatusText( "Ready" )
		wx.Yield()
		self.Layout()
		self.Show()

	def OnZoom( self, event ):
		if self.account.window: self.account.window.OnZoom( 3 )

	def OnClose( self, event ):
		self.account.window.bbook.RemovePage( common.get_page_index( self.account.window.bbook, self ) )
		self.account.window.bbook.Refresh()
		self.bin.editor = None
		self.Destroy()

	def create_menu_items( self ):
		# The instance menu
		menu = wx.Menu()
		menu.Append( ID_INS_CREATE, "&Create", " Create a new instance" )
		menu.Append( ID_INS_EDIT, "&Edit", " Edit the selected instance" )
		menu.Append( ID_INS_COPY, "&Copy", " Copy the selected instance to apply" )
		menu.AppendSeparator()
		menu.Append( ID_INS_CLONE, "C&lone", " Clone the selected instance" )
		menu.Append( ID_INS_DELETE, "&Delete", " Delete the selected instance" )
		self.Bind( wx.EVT_MENU, self.OnInstanceCreate, id=ID_INS_CREATE )
		self.Bind( wx.EVT_MENU, self.OnInstanceEdit, id=ID_INS_EDIT )
		self.Bind( wx.EVT_MENU, self.OnInstanceCopy, id=ID_INS_COPY )
		self.Bind( wx.EVT_MENU, self.OnInstanceClone, id=ID_INS_CLONE )
		self.Bind( wx.EVT_MENU, self.OnInstanceDelete, id=ID_INS_DELETE )
		self.menu = menu

	def OnTimer( self, event ):
		self.GetPage()

	def OnBeginDrag( self, event ):
		ins = self.instances[self.current_page][self.currentItem]
		if ins is None: return
		data = wx.PyTextDataObject()
		instag = "%s.%s|%s.%s" % ( self.bin['id'], ins['instance_id'], self.bin['name'], ins['instance_name'] )
		data.SetText( instag )
		ds = wx.DropSource( self )
		ds.SetData( data )
		result = ds.DoDragDrop()

	def reset_values( self ):
		self.instances 			= {}
		self.variable_choice.SetSelection( 0 )
		self.current_variable 	= ''
		self.current_rel		= '='
		self.current_pattern	= ''
		self.current_max		= common.default_instances_rpp
		self.current_page		= 0
		self.total_pages		= 0
		self.total_instances	= 0
		self.filter_dirty		= False

	def OnShowByChange( self, event ):
		variable = self.variable_choice.GetStringSelection()
		variable = variable.strip()
		if variable == self.current_variable: return
		self.filter_dirty = True
		self.current_variable = variable
		self.find_text.Enable( self.current_variable != '' )
		self.find_rel_button.Enable( self.current_variable != '' )
		if self.current_variable != '':
			self.find_text.SetFocus()
		self.update_next_prev_buttons()

	def OnRelChange( self, event ):
		self.filter_dirty = True
		if self.current_rel == '=':
			self.current_rel = '~'
			self.find_rel_button.SetBitmapLabel( images.getContainsBitmap() )
		elif self.current_rel == '~':
			self.current_rel = '!='
			self.find_rel_button.SetBitmapLabel( images.getNotEqualsBitmap() )
		elif self.current_rel == '!=':
			self.current_rel = '!~'
			self.find_rel_button.SetBitmapLabel( images.getNotContainsBitmap() )
		elif self.current_rel == '!~':
			self.current_rel = '='
			self.find_rel_button.SetBitmapLabel( images.getEqualsBitmap() )
		self.find_text.SetFocus()
		self.update_next_prev_buttons()

	def OnFindTextKeyPress( self, event ):
		self.filter_dirty = True
		self.current_pattern = self.find_text.GetValue()
		self.update_next_prev_buttons()

	def GetPage( self ):
		# Set the filter attibs,
		self.list.DeleteAllItems()
		if self.filter_dirty:
			self.instances		= {}
			self.filter_dirty	= False
			self.current_page	= 1

		# Update the status bar
		if self.account.window: self.account.window.SetStatusText( "Getting page %s ..." % self.current_page )
		wx.Yield()
		wx.Yield()
		wx.Yield()
		# Do we use the cache or download ?
		try:
			cache = self.instances[ self.current_page ]
		except KeyError:
			cache = None

		if cache:
			for ins in cache:
				ins.list_index = self.AppendInstance( ins )
		else:
			# Make the call
			cdom = "<instances_get binder_id=\"%s\" variable=\"%s\" relation=\"%s\" pattern=\"%s\" max=\"%s\" page=\"%s\" />" % \
					( self.bin['id'], self.current_variable, self.current_rel, self.current_pattern, self.current_max, self.current_page )
			cur = wx.BusyCursor()
			cnts = None
			try:
				xmlstring = self.account.execute( 'base', "instances_get", DOM=cdom )
				#xmlstring = common.uni2str( xmlstring )
				xmlstring = common.prepare_xml( xmlstring )
				cdom 	= minidom.parseString( xmlstring )
				cnts	= cdom.firstChild
			except:
				if self.account.window: self.account.window.SetStatusText( "Ready" )
			del cur
			if not cnts: return
			self.total_pages 	= int( cnts.attributes["pages"].value )
			self.total_instances = int( cnts.attributes["count"].value )
			self.instances[ self.current_page ] = []
			cache = self.instances[ self.current_page ]
			for idom in cnts.getElementsByTagName("instance"):
				ins = None
				try:
					ins = rex.binders.instance( self.account, self.bin, idom.toxml() )
				except:
					common.show_error( "failed to parse instance [[%s]]" % idom.toxml().encode( 'utf-8' ), False )
				if not ins: continue
				cache.append( ins )
				# Create a list item
				ins.list_index = self.AppendInstance( ins )
			#except Exception:
			#	print "Failed to load account contacts."
		self.list.SetColumnWidth(0, wx.LIST_AUTOSIZE)
		self.list.SetColumnWidth(1, wx.LIST_AUTOSIZE)
		label = "   Page %s of %s [%s total]   " % (self.current_page, self.total_pages, self.total_instances)
		#print "Label ", label
		self.pager.SetLabel( label )
		self.update_next_prev_buttons()
		if self.account.window: self.account.window.SetStatusText( "Ready" )
		wx.Yield()

	def GetNext( self, event=None ):
		#if ( not self.filter_dirty ) and ( self.current_page >= self.total_pages ): return
		self.timer.Stop()
		self.current_page = self.current_page + 1
		# override?
		if self.filter_dirty:
			self.instances		= {}
			self.filter_dirty	= False
			self.current_page	= 1

		if self.account.window: self.account.window.SetStatusText( "Getting page %d ..." % self.current_page )
		#wx.Yield()
		# Cache exists already?
		try:
			cache = self.instances[ self.current_page ]
			self.GetPage()
			return
		except KeyError:
			pass
		self.timer.Start( 700, 1 )

	def GetPrev( self, event ):
		if self.current_page <= 1: return
		self.timer.Stop()
		self.current_page = self.current_page - 1
		if self.account.window: self.account.window.SetStatusText( "Getting page %d ..." % self.current_page )
		#wx.Yield()
		# Cache exists already?
		try:
			cache = self.instances[ self.current_page ]
			self.GetPage()
			return
		except KeyError:
			pass
		self.timer.Start( 700, 1 )

	def update_next_prev_buttons( self ):
		#print "Checking np %s, %s" % ( self.current_page, self.total_pages )
		if self.filter_dirty:
			self.next_button.Enable( True )
			self.prev_button.Enable( False )
			return
		#
		if self.current_page >= self.total_pages:
			#print "DISABLING next_button"
			self.next_button.Enable( False )
		else:
			#print "ENABLING next_button"
			self.next_button.Enable( True )

		if self.current_page <= 1:
			#print "DISABLING prev_button"
			self.prev_button.Enable( False )
		else:
			#print "ENABLING prev_button"
			self.prev_button.Enable( True )

	#~ def enable_topbar( self, enable ):
		#~ self.variable_choice.Enable( enable )
		#~ self.find_text.Enable( enable and ( self.variable_choice.GetSelection() != 0 ) )
		#~ self.rpp_choice.Enable( enable )
		#~ if enable:
			#~ label = "Get"
		#~ else:
			#~ label = "Reset"
		#~ self.get_button.SetLabel( label )

	#~ def enable_botbar( self, enable ):
		#~ self.prev_button.Enable( enable )
		#~ self.next_button.Enable( enable )
		#~ if not enable: self.pager.SetLabel( "" )
		#~ #print "enable_botbar"

	def OnListRightClick( self, event ):
		common.dprint("OnListRightClick")
		try:
			xpos = event.m_x
			ypos = event.m_y
			self.PopupMenu( self.menu, wx.Point( xpos + 5, ypos + 45) )
		except AttributeError, e:
			# It may be an EVT_COMMAND_RIGHT_CLICK event, which has no x/y data
			if(type(event) == wx.CommandEvent):
				# Try to guess right location from selection
				point = self.list.GetItemPosition(self.currentItem)
				self.PopupMenu( self.menu, wx.Point( point.x + 10, point.y + 35) )
			else:
				common.dprint("Unrecognized event when right-clicking on an instance list: "+type(event))

	def OnItemDoubleClick( self, event ):
		#~ print "OnItemDoubleClick"
		self.OnInstanceEdit( event )

	def OnItemActivated( self, event ):
		self.currentItem = event.m_itemIndex

	def AppendInstance( self, ins ):
		x = self.list.InsertImageStringItem( sys.maxint, ins['instance_id'], self.instance_icon )
		self.list.SetStringItem( x , 1, ins["instance_name"] )
		self.list.SetItemData( x, x )
		return x

	def OnInstanceEdit( self, event ):
		ins = self.instances[self.current_page][self.currentItem]
		if ins is None: return
		#~ print "Editing contact %s" % con["first_name"]
		pi = common.find_page_index( self.account.window.ebook, ins )
		if pi >= 0:
			self.account.window.ebook.SetSelection( pi )
			return
		ins.editor = instance( self.account, ins, self.currentItem )
		self.account.window.ebook.AddPage( ins.editor, ins.editor.get_label_text() )
		pi = common.get_page_index( self.account.window.ebook, ins.editor )
		try:
			self.account.window.ebook.SetSelection( pi )
			self.account.window.ebook.SetPageImage( pi, self.account.window.icon_from_rex_object( ins ) )
		except:
			common.show_error("Failed to switch to editor", False)

	def OnInstanceCreate( self, event = None ):
		dlg = wx.TextEntryDialog( self, "Please enter the name of the new instance",
										"Create Instance",
										"Instance Name" )
		dlg.SetValue( 'New instance' )
		if dlg.ShowModal() != wx.ID_OK:
			ins = None
			dlg.Destroy()
			return
		ins = rex.binders.instance( self.account, self.bin, None )
		new_name = dlg.GetValue().lower()
		dlg.Destroy()
		new_name = new_name.replace("[", "" )
		new_name = new_name.replace("]", "" )
		new_name = new_name.replace("#", "" )
		new_name = new_name.replace("$", "" )
		new_name = new_name.replace("'", "" )
		new_name = new_name.replace("\"", "" )
		new_name = new_name.replace(".", "_" )
		ins['instance_name'] = new_name
		if not ins.create(): return
		cache 	= self.get_cache() #self.instances[ self.current_page ]
		cache.append( ins )
		# Create a list item
		ins.list_index = self.AppendInstance( ins )
		self.currentItem = ins.list_index
		self.list.SetColumnWidth(0, wx.LIST_AUTOSIZE)
		self.list.SetColumnWidth(1, wx.LIST_AUTOSIZE)
		self.OnInstanceEdit( None )
		self.filter_dirty = True

	def OnInstanceCopy( self, event ):
		ins = self.instances[self.current_page][self.currentItem]
		if ins is None: return
		selected_instance = "%s.%s|%s.%s" % ( self.bin['id'], ins['instance_id'], self.bin['name'], ins['instance_name'] )
		# Now let's put it in the clipboard
		clipdata = wx.TextDataObject()
		clipdata.SetText( selected_instance )
		wx.TheClipboard.Open()
		wx.TheClipboard.SetData( clipdata )
		wx.TheClipboard.Close()

	def OnInstanceClone( self, event ):
		ins = self.instances[self.current_page][self.currentItem]
		if ins is None: return
		# Create the new instance on the server, that will give it an ID
		new_iid = ins.clone()
		if len( new_iid.strip() ) < 1: return
		new_ins = rex.binders.instance( self.account, self.bin, None )
		new_ins["instance_id"] = new_iid
		new_ins["instance_name"] = "cloned %s" % ins["instance_name"]
		new_ins["binder_id"] = self.bin["id"]
		new_ins.binder = self.bin
		cache 	= self.get_cache() #self.instances[ self.current_page ]
		cache.append( new_ins )
		# Create a list item
		new_ins.list_index = self.AppendInstance( new_ins )
		self.currentItem = new_ins.list_index
		self.list.SetColumnWidth(0, wx.LIST_AUTOSIZE)
		self.list.SetColumnWidth(1, wx.LIST_AUTOSIZE)
		self.OnInstanceEdit( None )
		self.filter_dirty = True

	def OnInstanceDelete( self, event ):
		test = self.instances[self.current_page][self.currentItem]
		if test is None: return
		bid = test['binder_id']
		sel = ""
		ins = self.get_selected()
		if ins is None: return
		common.dprint( "selected instances:" )
		for sp in ins :
			common.dprint( sp['instance_id'] )
			if sel == "":
				sel = sp['instance_id']
			else :
				sel += ", " + sp['instance_id']
		# Confirm delete
		# res = wx.MessageBox( "Are you sure you want to delete this instance?", "Confirm Delete", wx.YES_NO )
		choices = ['all selected instances', 'all EXCEPT selected instances', 'all binder instances']
		dlg = wx.SingleChoiceDialog(self.bin.account.window.bbook, 'Delete Instances', 'Delete:', choices, wx.CHOICEDLG_STYLE)
		if dlg.ShowModal() == wx.ID_OK:
			choice = dlg.GetStringSelection()
		dlg.Destroy()
		common.dprint( "chose:",choice )
		data = { "sel":"", "unsel":"", "all":"" }
		data["sel"] = "<root binder_id=\"" + bid + "\" id=\"" + sel + "\"></root>"
		data["unsel"] = "<root binder_id=\"" + bid + "\" id=\"" + sel + "\" delete_all=\"except\"></root>"
		data["all"] = "<root binder_id=\"" + bid + "\" delete_all=\"yes\"></root>"
		choice = {
			'all selected instances': lambda data: data["sel"],
			'all EXCEPT selected instances': lambda data: data["unsel"],
			'all binder instances': lambda data: data["all"]
		}[choice](data)
		common.dprint( "dom:", choice )
		res = self.account.execute( 'base', "instance_delete", DOM=choice )
		if res :
			pi = common.find_page_index( self.account.window.ebook, test )
			if pi >= 0:
				self.account.window.ebook.RemovePage( pi )
				ins.editor = None
			self.filter_dirty = True
			self.GetPage()
		#if res != wx.YES: return
		'''if ins.delete():
			pi = common.find_page_index( self.account.window.ebook, ins )
			if pi >= 0:
				self.account.window.ebook.RemovePage( pi )
				ins.editor = None
			self.filter_dirty = True
			self.GetPage()'''

	def get_cache( self ):
		try:
			cache = self.instances[ self.current_page ]
		except KeyError:
			self.instances[ self.current_page ] = []
			cache = self.instances[ self.current_page ]
		return cache

	def get_selected( self ):
		sel = []
		count = self.list.GetItemCount()
		if count < 1: return sel
		for i in range( 0, count ):
			if self.list.IsSelected( i ):
				sel.append( self.instances[ self.current_page ][i] )
		return sel

	def get_unselected( self ):
		sel = []
		count = self.list.GetItemCount()
		if count < 1: return sel
		for i in range( 0, count ):
			if not self.list.IsSelected( i ):
				sel.append( self.instances[ self.current_page ][i] )
		return sel

	def delete_selected( self, event = None ):
		# Confirm
		res = wx.MessageBox( "Are you sure you want to delete selected contact(s)?", "Confirm Delete", wx.YES_NO )
		if res != wx.YES: return
		cons = self.get_selected()
		if len( cons ) < 1: return
		# Construct the DOM
		cdom = ""
		for con in cons:
			cdom = cdom + ( "<c id=\"%s\" />" % con["id"] )
		cdom = "<cs>" + cdom + "</cs>"
		try:
			res = self.account.execute( 'base', "contacts_delete", DOM=cdom )
		except:
			common.show_error("Failed to delete")
			return
		if res:
			# Refresh this page
			self.GetPage()

	def for_group( self, grp ):
		self.qualifier	= "GROUP"
		self.qid		= grp["id"]
		self.rex_object = grp

	#~ def for_pub_sub( self, pub ):
		#~ self.qualifier	= "PUBSUB"
		#~ self.qid		= pub["id"]

	#~ def for_pub_BLK( self, BLK ):
		#~ self.qualifier	= "PUBBLK"
		#~ self.qid		= pub["id"]

	def set_value( self, value ):
		common.dprint( self.__class__, 'set value', value )

	def get_value( self ):
		common.dprint( self.__class__, 'get value' )

	def set_readwrite( self, rw ):
		common.dprint( self.__class__, 'set readwrite', rw )


class instance( base.editor ):
	def __init__( self, account, ins, listindex ):
		base.editor.__init__( self, account, ins, listindex )
		self.load_rex_object()

	def load_rex_object( self ):
		if self.rex_object is None: return
		# Instances need to be loaded from rex
		if self.account.window: self.account.window.SetStatusText("Loading instance...")
		wx.Yield()
		dom = "<instance instance_id='%s' binder_id='%s' />" % ( self.rex_object["instance_id"], self.rex_object.binder["id"] )
		#print "instance_get using the following dom:%s" % dom
		cur = wx.BusyCursor()
		try:
			xmlstring = self.rex_object.execute( "get2", dom=dom )
			xmlstring = common.uni2str( xmlstring )
			#print "InstanceSUI got xmlstring parsing - length ", len( xmlstring )
			self.rex_object.fromxml( xmlstring )
		except:
			common.show_error( "failed to load the issue" )
		del cur
		# Add the standard properties
		base.editor.load_rex_object( self )
		# Reposition the splitter
		self.vSplitter.SetSashPosition( self.sash_pos )
		if self.account.window: self.account.window.SetStatusText( "Ready" )

	def OnSave( self, event ):
		base.editor.OnSave( self, event )
		self.account.window.binder_control.rebuild_mirrors( self.rex_object.binder )


class BinderProps( wx.Dialog ):
	'''Provides the UI to manipulate a binder's properties'''
	def __init__( self, parent, bin ):
		self.currentItem = -1
		self.binder_control = parent
		wx.Dialog.__init__( self, parent, -1, "Binder Properties",
						   wx.DefaultPosition, wx.Size( 350, 300 )  )
		if bin["kind"] == "SYSTEM": return
		if bin["id"] <= "1": return

		self.bin = bin
		name = bin["name"]
		print dir( bin )
		if bin.mirror:
			name = bin.mirror_name

		# Create the input fields
		self.name_control = wx.TextCtrl( self, -1, name )
		self.type_control = wx.CheckBox( self, -1, "This is a Mirror binder", style=wx.NO_BORDER )
		self.type_control.Bind( wx.EVT_CHECKBOX, self.MirrorClicked )
		self.bins_control = wx.ListCtrl(self, -1, style=wx.LC_REPORT )
		self.bins_control.Bind( wx.EVT_LIST_ITEM_SELECTED, self.OnItemActivated)
		info = wx.ListItem()
		info.m_mask = wx.LIST_MASK_TEXT
		info.m_image = -1
		info.m_format = 0
		info.m_text = "Available Binders"
		self.bins_control.InsertColumnInfo(0, info)

		if bin.mirror:
			self.type_control.SetValue( True )

		# Disable the checkbox if the binder has instances and values
		if ( len( bin.instances ) > 0 ) or ( len( bin.variables ) > 0 ):
			self.type_control.SetValue( False )
			self.type_control.Enable( False )
			self.bins_control.Enable( False )

		self.sizer = wx.BoxSizer( wx.VERTICAL )

		self.sizer.Add( self.name_control, 0, wx.EXPAND | wx.EAST | wx.WEST | wx.NORTH, 5 )
		self.sizer.Add( self.type_control, 0, wx.EXPAND | wx.EAST | wx.WEST, 3 )
		self.sizer.Add( self.bins_control, 1, wx.EXPAND | wx.GROW | wx.EAST | wx.WEST, 3 )
		self.sizer.Add( wx.StaticText( self, -1, ""), 0, wx.EXPAND | wx.GROW | wx.SOUTH | wx.NORTH, 3 )

		# Add the buttons
		self.button_sizer = wx.BoxSizer( wx.HORIZONTAL )
		btn = wx.Button( self, wx.ID_OK, "&Save" )
		btn.SetDefault()
		self.button_sizer.Add( (10,10), 1, 1 )
		self.button_sizer.Add( btn, 1, 0 )
		self.button_sizer.Add( (10,10), 1, 1 )
		btn = wx.Button( self, wx.ID_CANCEL, "&Cancel" )
		self.button_sizer.Add( btn, 1, 0 )
		self.button_sizer.Add( (10,10), 1, 1 )

		self.sizer.Add( self.button_sizer, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.SOUTH, 20 )
		icon = icon_manager.get_icon( "Binder" )
		self.SetIcon( icon )
		self.SetSizer( self.sizer )
		self.SetAutoLayout( 1 )
		# Windows needs this call
		self.Layout()

		self.load_bins()
		if bin.mirror:
			self.type_control.SetValue( True )
		self.set_bins_enabled()

	def load_bins( self ):
		bins = [ bin for bin in self.binder_control.binders if ( bin["kind"] == "") and ( bin["id"] != self.bin["id"] ) ]
		x = 0
		sel = -1
		for bin in bins:
			name = bin["name"]
			self.bins_control.InsertStringItem( x, bin["name"] )
			self.bins_control.SetItemData( x, int( bin["id"] ) )
			if ( self.bin.mirror ) and ( name.upper() == self.bin.original_name.strip().upper() ):
				sel = x
			x = x + 1
		self.bins_control.SetColumnWidth(0, wx.LIST_AUTOSIZE)
		if sel > -1: self.bins_control.Select( sel, True )

	def set_bins_enabled( self ):
		if self.type_control.GetValue():
			self.bins_control.Enable( True )
			self.bins_control.Select( 0, True )
		else:
			self.bins_control.Enable( False )
		if self.currentItem > -1:
			#item = self.bins_control.GetItem( self.currentItem )
			self.bins_control.Select( self.currentItem, False )

	def MirrorClicked( self, event ):
		#print "Mirror Clicked ", self.type_control.GetValue()
		self.set_bins_enabled()

	def GetValue( self ):
		if self.type_control.GetValue():
			# Mirror
			item = self.bins_control.GetItem( self.currentItem )
			self.bin.original_name	= item.GetText()
			self.bin['mirror_id']	= item.GetItemData()
			self.bin["name"] 		= self.name_control.GetValue()
			self.bin.mirror			= True
			ret = self.bin["name"] + " (mirror of " + self.bin.original_name + ")"
		else:
			self.bin["name"] 		= self.name_control.GetValue()
			self.bin["kind"] 		= ""
			self.bin.original_name 	= ""
			ret = "[ " + self.bin["id"] + " ] " + self.name_control.GetValue()
		return ret

	def OnItemActivated(self, event):
		'''Sets the internal currentItem variable to the currently selected account list item'''
		self.currentItem = event.m_itemIndex
